/**
 * Fichier LecteurSax.java : Définition de classe
 * fr.unice.gnpt.core.init.data.LecteurSax : Analyseur Sax des données initiales
 * de l'application
 * 
 * Auteurs : Groupe GNPT : Gastinel, Nicolas, Pellegrino, Trovato
 * 
 * $Id: LecteurSax.java 490 2008-11-12 19:26:10Z Cyprien NICOLAS $
 */
package fr.unice.gnpt.core.init.data;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;

import org.xml.sax.Attributes;
import org.xml.sax.helpers.XMLFilterImpl;

import fr.unice.gnpt.core.Cours;
import fr.unice.gnpt.core.Enseignant;
import fr.unice.gnpt.core.Enseignement;
import fr.unice.gnpt.core.Service;
import fr.unice.gnpt.core.ServiceDejaValideException;
import fr.unice.gnpt.core.StatutEnseignant;
import fr.unice.gnpt.core.TacheAdministrative;
import fr.unice.gnpt.core.util.Journal;

/**
 * Classe de lecture et d'enregistrement des données initiales
 * 
 * @author gnpt
 * @version 0.1.$LastChangeRevision$
 */
public class LecteurSax extends XMLFilterImpl {

	private HashMap<String, Cours> cours;
	private HashMap<String, Enseignant> enseignants;
	private HashSet<Service> services;
	
	/**
	 * Constructeur pour le LecteurSax
	 */
	public LecteurSax() {
		this.cours = new HashMap<String, Cours>();
		this.enseignants = new HashMap<String, Enseignant>();
		this.services = new HashSet<Service>();
	}

	/**
	 * @see org.xml.sax.helpers.XMLFilterImpl#startElement(java.lang.String,
	 *      java.lang.String, java.lang.String, org.xml.sax.Attributes)
	 */
	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes atts) {
		if (localName == "cours") {
			analyseCours(atts);
		} else if (localName == "enseignant") {
			analyseEnseignant(atts);
		} else if (localName == "service") {
			analyseService(atts);
		}
	}

	private void analyseCours(Attributes atts) {
		Cours cours1 = new Cours();
		String nomCours = null;

		int index = atts.getIndex("nom");
		if (index >= 0) {
			nomCours = atts.getValue(index);
		} else { // car nom ne peut être null
			nomCours = new String("Inconnu");
		}
		cours1.setNomCours(nomCours);

		if ((index = atts.getIndex("heuresCM")) >= 0) {
			cours1.setNbHeuresCM(Integer.parseInt(atts.getValue(index)));
		}

		if ((index = atts.getIndex("heuresTD")) >= 0) {
			cours1.setNbHeuresTD(Integer.parseInt(atts.getValue(index)));
		}

		if ((index = atts.getIndex("heuresTP")) >= 0) {
			cours1.setNbHeuresTP(Integer.parseInt(atts.getValue(index)));
		}

		if ((index = atts.getIndex("groupesTD")) >= 0) {
			cours1.setNbGroupesTD(Integer.parseInt(atts.getValue(index)));
		}

		if ((index = atts.getIndex("groupesTP")) >= 0) {
			cours1.setNbGroupesTP(Integer.parseInt(atts.getValue(index)));
		}

		this.cours.put(cours1.getNomCours(), cours1);
	}

	private void analyseEnseignant(Attributes atts) {

		Enseignant prof = new Enseignant("", "");
		int index;

		if ((index = atts.getIndex("nom")) >= 0) {
			prof.setNom(atts.getValue(index));
		}

		if ((index = atts.getIndex("prénom")) >= 0) {
			prof.setPrenom(atts.getValue(index));
		}

		if ((index = atts.getIndex("statut")) >= 0) {
			String statut = atts.getValue(index);
			if (statut.equalsIgnoreCase("MCF")) {
				prof.setStatut(StatutEnseignant.MC);
			} else if (statut.equalsIgnoreCase("PRAG")) {
				prof.setStatut(StatutEnseignant.PRAG);
			} else {
				prof.setStatut(StatutEnseignant.PR);
			}
		}

		this.enseignants.put(prof.getNom(), prof);
	}

	private void analyseService(Attributes atts) {
		int index;
		boolean aValider = true;
		Service service = null;
		Enseignant e;

		if ((index = atts.getIndex("nomEnseignant")) >= 0) {
			e = this.enseignants.get(atts.getValue(index).toUpperCase());
		} else {
			Journal.getJournal().logAvertissement(
					"analyseService: Donnée non cohérente, ignorée.");
			return;
		}

		if ((index = atts.getIndex("nonValide")) >= 0) {
			/*
			 * On ne valide pas ce service d'office, on ignore la valeur de
			 * l'attribut
			 */
			aValider = false;
		}

		if ((index = atts.getIndex("nomCours")) >= 0) {
			// C'est un cours
			service = new Enseignement();
			Enseignement enseignement = (Enseignement) service;
			Cours c = this.cours.get(atts.getValue(index));

			enseignement.setCours(c);
			enseignement.setEnseignant(e);

			if ((index = atts.getIndex("cmEnCharge")) >= 0) {
				if (atts.getValue(index).equalsIgnoreCase("oui")) {
					enseignement.setCMEnCharge(true);
				} else {
					enseignement.setCMEnCharge(false);
				}
			}

			if ((index = atts.getIndex("nbGroupesTD")) >= 0) {
				int nbGroupes;
				try {
					nbGroupes = Integer.parseInt(atts.getValue(index));
				} catch (NumberFormatException ex) {
					nbGroupes = 0;
				}
				enseignement.setNbGroupesTDEnCharge(nbGroupes);
			}

			if ((index = atts.getIndex("nbGroupesTP")) >= 0) {
				int nbGroupes;
				try {
					nbGroupes = Integer.parseInt(atts.getValue(index));
				} catch (NumberFormatException ex) {
					nbGroupes = 0;
				}
				enseignement.setNbGroupesTPEnCharge(nbGroupes);
			}

			//e.ajouterEnseignement(enseignement);

		} else if ((index = atts.getIndex("nomTache")) >= 0) {
			// C'est une tâche
			service = new TacheAdministrative();
			TacheAdministrative tache = (TacheAdministrative) service;
			tache.setDescription(atts.getValue(index));
			tache.setEnseignant(e);

			if ((index = atts.getIndex("hTD")) >= 0) {
				int nbHeuresTD;
				try {
					nbHeuresTD = Integer.parseInt(atts.getValue(index));
				} catch (NumberFormatException ex) {
					nbHeuresTD = 20; // Valeur par défaut ?!
				}
				tache.setNbHeuresEquivalent(nbHeuresTD);
			}
			//e.ajouterTacheAdministrative(tache);
		}
		
		if (service != null) {
			if (aValider) {
				try {
					service.valider();
				} catch (ServiceDejaValideException ex) {
					Journal.getJournal().logException(ex);
				}
			}
			this.services.add(service);
		}
	}

	/**
	 * @return la collection d'enseignant récupérée par le lecteur.
	 */
	public Collection<Enseignant> getCollectionEnseignants() {
		return this.enseignants.values();
	}

	/**
	 * @return la collection de cours récupérée par le lecteur.
	 */
	public Collection<Cours> getCollectionCours() {
		return this.cours.values();
	}

	/**
	 * @return la collection de services récupérée par le lecteur.
	 */
	public Collection<Service> getCollectionServices() {
		return this.services;
	}

}
